package com.zz.common.codeGenerator.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.common.base.dto.PageListResultDto;
import com.zz.common.base.enums.BaseExceptionEnum;
import com.zz.common.base.param.QueryParam;
import com.zz.common.codeGenerator.dto.GenFormSchemaDto;
import com.zz.common.codeGenerator.entity.GenFormSchema;
import com.zz.common.codeGenerator.mapper.GenFormSchemaMapper;
import com.zz.common.codeGenerator.service.GenFormSchemaService;
import com.zz.common.constants.BaseConstant;
import com.zz.common.exception.ExceptionFactory;
import com.zz.common.utils.common.UUIDGenerator;
import com.zz.common.utils.mapper.BeanMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 表单Schema配置 服务实现类
 *
 * @author zl
 * @since 2025-11-22 08:29:41
 */
@Service
@Slf4j
public class GenFormSchemaServiceImpl extends ServiceImpl<GenFormSchemaMapper, GenFormSchema> implements GenFormSchemaService {

    @Resource
    private GenFormSchemaMapper genFormSchemaMapper;

    @Override
    public PageListResultDto<GenFormSchemaDto> queryWithPage(GenFormSchemaDto genFormSchemaDto, QueryParam queryParam) {
        Page<GenFormSchema> page = new Page<>(queryParam.getPageNum(), queryParam.getPageSize());
        QueryWrapper<GenFormSchema> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        if (StringUtils.isNotBlank(genFormSchemaDto.getSchemaId())) {
            wrapper.eq("schema_id", genFormSchemaDto.getSchemaId());
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getTableId())) {
            wrapper.eq("table_id", genFormSchemaDto.getTableId());
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getTableName())) {
            wrapper.like("table_name", "%" + genFormSchemaDto.getTableName() + "%");
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getVersion())) {
            wrapper.eq("version", genFormSchemaDto.getVersion());
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getCreateBy())) {
            wrapper.eq("create_by", genFormSchemaDto.getCreateBy());
        }
        if (ObjectUtil.isNotEmpty(genFormSchemaDto.getCreateDateRange())) {
            wrapper.between("create_date", genFormSchemaDto.getCreateDateRange().get(0), genFormSchemaDto.getCreateDateRange().get(1));
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getUpdateBy())) {
            wrapper.eq("update_by", genFormSchemaDto.getUpdateBy());
        }
        if (ObjectUtil.isNotEmpty(genFormSchemaDto.getUpdateDateRange())) {
            wrapper.between("update_date", genFormSchemaDto.getUpdateDateRange().get(0), genFormSchemaDto.getUpdateDateRange().get(1));
        }
        if (StringUtils.isNotBlank(genFormSchemaDto.getRemark())) {
            wrapper.eq("remark", genFormSchemaDto.getRemark());
        }
        page = genFormSchemaMapper.selectPage(page, wrapper);
        List<GenFormSchema> genFormSchemas = genFormSchemaMapper.selectList(page, wrapper);
        List<GenFormSchemaDto> genFormSchemaDtos = BeanMapper.mapList(genFormSchemas, GenFormSchema.class, GenFormSchemaDto.class);
        return new PageListResultDto<>((int) page.getCurrent(), (int) page.getTotal(), queryParam.getPageSize(), genFormSchemaDtos);
    }

    @Override
    public List<GenFormSchemaDto> queryWithNoPage(GenFormSchemaDto genFormSchemaDto) {
        QueryWrapper<GenFormSchema> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        List<GenFormSchema> genFormSchemas = genFormSchemaMapper.selectList(wrapper);
        return BeanMapper.mapList(genFormSchemas, GenFormSchema.class, GenFormSchemaDto.class);
    }

    @Override
    public GenFormSchemaDto queryById(String id) {
        if (StringUtils.isBlank(id)) {
            return null;
        }
        GenFormSchema genFormSchema = genFormSchemaMapper.selectById(id);
        if (genFormSchema == null || BaseConstant.YES.equals(genFormSchema.getDelFlag())) {
            return null;
        }
        GenFormSchemaDto dto = BeanMapper.map(genFormSchema, GenFormSchemaDto.class);
        return dto;
    }

    @Override
    public GenFormSchemaDto queryByTableId(String tableId) {
        if (StringUtils.isBlank(tableId)) {
            return null;
        }
        QueryWrapper<GenFormSchema> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        wrapper.eq("table_id", tableId);
        GenFormSchema genFormSchema = genFormSchemaMapper.selectOne(wrapper);
        if (genFormSchema == null) {
            return null;
        }
        GenFormSchemaDto dto = BeanMapper.map(genFormSchema, GenFormSchemaDto.class);
        return dto;
    }

    @Override
    public List<GenFormSchemaDto> queryByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        List<GenFormSchema> genFormSchemas = genFormSchemaMapper.selectByIds(ids);
        if (CollectionUtils.isEmpty(genFormSchemas)) {
            return new ArrayList<>();
        }
        List<GenFormSchemaDto> dtos = BeanMapper.mapList(genFormSchemas, GenFormSchema.class, GenFormSchemaDto.class);
        return dtos;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenFormSchemaDto save(GenFormSchemaDto genFormSchemaDto) {
        GenFormSchemaDto result = insert(genFormSchemaDto);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GenFormSchemaDto> saveBatch(List<GenFormSchemaDto> genFormSchemaDtos) {
        List<GenFormSchemaDto> results = insertList(genFormSchemaDtos);
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GenFormSchemaDto> saveOrUpdateWithTableIdBatch(List<GenFormSchemaDto> genFormSchemaDtos) {
        if (CollectionUtils.isEmpty(genFormSchemaDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量保存或更新时，参数不能为空");
        }

        List<GenFormSchemaDto> results = new ArrayList<>();
        for (GenFormSchemaDto dto : genFormSchemaDtos) {
            if (StringUtils.isBlank(dto.getTableId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量保存或更新时，tableId不能为空");
            }
            GenFormSchemaDto latest = queryLatestByTableId(dto.getTableId());
            if (latest == null) {
                if (StringUtils.isBlank(dto.getSchemaId())) {
                    dto.setSchemaId(UUIDGenerator.generateUUID());
                }
                dto.setDelFlag(BaseConstant.NO);
                insert(dto);
            } else {
                dto.setSchemaId(latest.getSchemaId());
                dto.setDelFlag(BaseConstant.NO);
                updateById(dto);
            }
            results.add(dto);
        }
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenFormSchemaDto modify(GenFormSchemaDto genFormSchemaDto) {
        updateById(genFormSchemaDto);
        return genFormSchemaDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<GenFormSchemaDto> modifyBatch(List<GenFormSchemaDto> genFormSchemaDtos) {
        List<GenFormSchemaDto> results = updateList(genFormSchemaDtos);
        return results;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int trueDelete(String id) {
        GenFormSchema entity = new GenFormSchema();
        entity.setSchemaId(id);
        return genFormSchemaMapper.deleteById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void trueDeleteBatch(List<String> ids) {
        genFormSchemaMapper.deleteByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void trueDeleteByTableIds(List<String> tableIds) {
        if (CollectionUtils.isEmpty(tableIds)) {
            return;
        }
        QueryWrapper<GenFormSchema> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        wrapper.in("table_id", tableIds);
        genFormSchemaMapper.delete(wrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(String id) {
        // 根据业务修改
        GenFormSchemaDto genFormSchemaDto = new GenFormSchemaDto();
        genFormSchemaDto.setSchemaId(id);
        deleteById(genFormSchemaDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBatch(List<String> ids) {
        // 根据业务修改
        deleteByIds(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenFormSchemaDto insert(GenFormSchemaDto genFormSchemaDto) {
        genFormSchemaDto.setSchemaId(UUIDGenerator.generateUUID());
        genFormSchemaDto.setDelFlag(BaseConstant.NO);
        GenFormSchema entity = BeanMapper.map(genFormSchemaDto, GenFormSchema.class);
        genFormSchemaMapper.insert(entity);
        return genFormSchemaDto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public GenFormSchemaDto insertWithId(GenFormSchemaDto genFormSchemaDto) {
        if (StringUtils.isBlank(genFormSchemaDto.getSchemaId())) {
            genFormSchemaDto.setSchemaId(UUIDGenerator.generateUUID());
        }
        genFormSchemaDto.setDelFlag(BaseConstant.NO);
        GenFormSchema entity = BeanMapper.map(genFormSchemaDto, GenFormSchema.class);
        genFormSchemaMapper.insert(entity);
        return genFormSchemaDto;
    }

    @Override
    public GenFormSchemaDto queryLatestByTableId(String tableId) {
        if (StringUtils.isBlank(tableId)) {
            return null;
        }
        QueryWrapper<GenFormSchema> wrapper = new QueryWrapper<>();
        wrapper.eq("del_flag", BaseConstant.NO);
        wrapper.eq("table_id", tableId);
        wrapper.orderByDesc("update_date");
        wrapper.orderByDesc("create_date");
        Page<GenFormSchema> page = new Page<>(1, 1);
        Page<GenFormSchema> resultPage = genFormSchemaMapper.selectPage(page, wrapper);
        if (resultPage.getRecords() == null || resultPage.getRecords().isEmpty()) {
            return null;
        }
        return BeanMapper.map(resultPage.getRecords().get(0), GenFormSchemaDto.class);
    }

    private List<GenFormSchemaDto> insertList(List<GenFormSchemaDto> genFormSchemaDtos) {
        if (CollectionUtils.isEmpty(genFormSchemaDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量插入时，参数不能为空");
        }
        List<GenFormSchema> insertList = new ArrayList<>();
        for (GenFormSchemaDto genFormSchemaDto : genFormSchemaDtos) {
            if (StringUtils.isBlank(genFormSchemaDto.getSchemaId())) {
                genFormSchemaDto.setSchemaId(UUIDGenerator.generateUUID());
            }
            genFormSchemaDto.setDelFlag(BaseConstant.NO);
            insertList.add(BeanMapper.map(genFormSchemaDto, GenFormSchema.class));
        }
        genFormSchemaMapper.insert(insertList, 1000);
        return genFormSchemaDtos;
    }

    private List<GenFormSchemaDto> updateList(List<GenFormSchemaDto> genFormSchemaDtos) {
        if (CollectionUtils.isEmpty(genFormSchemaDtos)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，参数不能为空");
        }
        for (GenFormSchemaDto genFormSchemaDto : genFormSchemaDtos) {
            if (StringUtils.isBlank(genFormSchemaDto.getSchemaId())) {
                throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量更新时，主键不能为空");
            }
        }
        List<GenFormSchema> genFormSchemaList = BeanMapper.mapList(genFormSchemaDtos, GenFormSchemaDto.class, GenFormSchema.class);
        genFormSchemaMapper.updateById(genFormSchemaList, 1000);
        return genFormSchemaDtos;
    }

    @Transactional(rollbackFor = Exception.class)
    public int updateById(GenFormSchemaDto genFormSchemaDto) {
        if (StringUtils.isBlank(genFormSchemaDto.getSchemaId())) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.INTERNAL_SERVER_ERROR, "更新时，主键不能为空");
        }
        GenFormSchema entity = BeanMapper.map(genFormSchemaDto, GenFormSchema.class);
        return genFormSchemaMapper.updateById(entity);
    }

    @Transactional(rollbackFor = Exception.class)
    public int deleteById(GenFormSchemaDto genFormSchemaDto) {
        genFormSchemaDto.setDelFlag(BaseConstant.YES);
        return updateById(genFormSchemaDto);
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteByIds(List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            throw ExceptionFactory.createBaseException(BaseExceptionEnum.NOT_FOUND, "批量删除时，参数不能为空");
        }
        for (String id : ids) {
            GenFormSchemaDto genFormSchemaDto = new GenFormSchemaDto();
            genFormSchemaDto.setSchemaId(id);
            genFormSchemaDto.setDelFlag(BaseConstant.YES);
            updateById(genFormSchemaDto);
        }
    }

}
